#ifndef __HTTP_PROT_HEADERS_H_
#define __HTTP_PROT_HEADERS_H_

#include <vector>
#include <string>


namespace httpprot
{
	enum GeneralHeader
	{
		GENERAL_HEADER_CACHE_CONTROL,
		GENERAL_HEADER_CONNECTION,
		GENERAL_HEADER_DATE,
		GENERAL_HEADER_MIME_VERSION,
		GENERAL_HEADER_PRAGMA,
		GENERAL_HEADER_TRAILER,
		GENERAL_HEADER_TRANSFER_ENCODING,
		GENERAL_HEADER_UPGRADE,
		GENERAL_HEADER_VIA,
		GENERAL_HEADER_WARNING
	};

	inline
	unsigned int GetNumGeneralHeaders( )
	{
		return 10;
	}

	inline
	const char * GetGeneralHeaderString( GeneralHeader header )
	{
		const char * headerToString[ ] =
		{
			"Cache-Control", // GENERAL_HEADER_CACHE_CONTROL
			"Connection", // GENERAL_HEADER_CONNECTION
			"Date", // GENERAL_HEADER_DATE
			"MIME-Version", // GENERAL_HEADER_MIME_VERSION
			"Pragma", // GENERAL_HEADER_PRAGMA
			"Trailer", // GENERAL_HEADER_TRAILER
			"Transfer-Encoding", // GENERAL_HEADER_TRANSFER_ENCODING
			"Upgrade", // GENERAL_HEADER_UPGRADE
			"Via", // GENERAL_HEADER_VIA
			"Warning" // GENERAL_HEADER_WARNING
		};

		return headerToString[ header ];
	}

	inline
	bool GetGeneralHeaderByString( const std::string& headerString, GeneralHeader& headerOut )
	{
		for( unsigned int i = 0; i < GetNumGeneralHeaders( ); ++i )
		{
			GeneralHeader header = (GeneralHeader) i;
			if( headerString == GetGeneralHeaderString( header ) )
			{
				headerOut = header;
				return true;
			}
		}

		return false;
	}

	class Headers
	{
	public:
		Headers( )
		{
		}

		~Headers( )
		{
		}

		void Clear( )
		{
			m_headers.clear( );
		}

		void AddGeneralHeader( GeneralHeader header, const std::string& value )
		{
			const char * headerString = GetGeneralHeaderString( header );
			m_generalHeaders.push_back( Header( headerString, value ) );
		}

		void AddHeader( const std::string& key, const std::string& value )
		{
			m_headers.push_back( Header( key, value ) );
		}

		bool GetHeader( const std::string& key, std::string& valueOut )
		{
			std::vector< Header >::iterator it = findHeaderWithKey( key );
			if( it == m_headers.end( ) )
				return false;
			valueOut = (*it).value;
			return true;
		}

		void WriteToBuffer( std::vector< char >& bufferOut ) const;

	private:
		struct Header
		{
			Header( )
			{
			}

			Header( const std::string& _key, const std::string& _value ) :
				key( _key ),
				value( _value )
			{
			}

			std::string key;
			std::string value;
		};

	private:
		std::vector< Header >::iterator findHeaderWithKey( const std::string& key );

	private:
		std::vector< Header > m_generalHeaders;
		std::vector< Header > m_headers;
	};
};

#endif